package com.luoye.lj.wstool.wsdm;

import com.luoye.lj.wstool.common.MysqlDbConfig;
import com.luoye.lj.wstool.common.StringUtils;
import com.luoye.lj.wstool.wsdm.entity.WsdtEntity;
import com.luoye.lj.wstool.wsdm.entity.WsdtEntityDesc;
import com.luoye.lj.wstool.wsdm.entity.WsdtField;
import com.luoye.lj.wstool.wsdm.entity.WsdtFieldDesc;
import net.sf.json.JSON;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * Created with IntelliJ IDEA.
 * User: Dave Liu
 * Date: 2020/2/10
 * Time: 23:06
 * To change this template use File | Settings | File Templates.
 */
public class TtoEntityResolver {
    public static WsdtEntity resolve(MysqlDbConfig dbConfig, String tableName){
        WsdtEntity wsdtEntity=null;

        Connection conn = null;
        Statement stmt = null;
        try{
            // 注册 JDBC 驱动
            Class.forName(dbConfig.getJdbcDriver());
            // 打开链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(dbConfig.getDbUrl(),dbConfig.getUserName(),dbConfig.getPassWord());
            // 执行查询
            System.out.println(" 实例化Statement对象...");
            stmt = conn.createStatement();
            String sql;
            sql = "SELECT\n" +
                    "    COLUMN_NAME AS 'columnName',\n" +
                    "    COLUMN_COMMENT AS 'columnComment',\n" +
                    "    IS_NULLABLE AS 'nullable',\n" +
                    "    DATA_TYPE AS 'dataType',\n" +
                    "    CHARACTER_MAXIMUM_LENGTH AS 'strLength',\n" +
                    "    NUMERIC_PRECISION AS 'numLength',\n" +
                    "    NUMERIC_SCALE AS 'numBit',\n" +
                    "\t\t(\n" +
                    "        CASE\n" +
                    "        WHEN EXTRA = 'auto_increment' THEN\n" +
                    "            1\n" +
                    "        ELSE\n" +
                    "            0\n" +
                    "        END\n" +
                    "    ) AS IsIdentity,\n" +
                    "    (\n" +
                    "        CASE\n" +
                    "        WHEN COLUMN_KEY = 'PRI' THEN\n" +
                    "            1\n" +
                    "        ELSE\n" +
                    "            0\n" +
                    "        END\n" +
                    "    ) AS IsPK\n" +
                    "FROM\n" +
                    "    information_schema.`COLUMNS`\n" +
                    "WHERE\n" +
                    "    TABLE_SCHEMA = '"+dbConfig.getDbName()+"' -- dm 是数据库名称\n" +
                    "AND TABLE_NAME = '"+tableName+"' -- base_auth_resource 是表名\n" +
                    "ORDER BY\n" +
                    "    ORDINAL_POSITION;";
            ResultSet rs = stmt.executeQuery(sql);

            wsdtEntity=new WsdtEntity();
            String names[]=tableName.split("_");
            String entityName="";
            for(String n:names){
                if(!"t".equals(n)){
                    entityName+= StringUtils.makeFirstCharUpcase(n);
                }
            }
            System.out.println("entityName->"+entityName);
            wsdtEntity.setEntityName(entityName+"");
            wsdtEntity.setTableName(tableName);
            wsdtEntity.setDescription("");
//            String entityPackageName=wsdtStr.substring(0,wsdtStr.lastIndexOf("."));
//            wsdtEntity.setEntityPackageName(entityPackageName);
            List<WsdtField> wsdtFieldList=new ArrayList<WsdtField>();
            wsdtEntity.setFieldList(wsdtFieldList);
            // 展开结果集数据库
            while(rs.next()){
                // 通过字段检索
                String columnName  = rs.getString("columnName");
                String columnComment = rs.getString("columnComment");
                //String nullable = rs.getString("nullable");
                String dataType = rs.getString("dataType");
                String IsIdentity = rs.getString("IsIdentity");
                String IsPK = rs.getString("IsPK");
                // 输出数据
                System.out.print("\ncolumnName: " + columnName);
                System.out.print("\ncolumnComment: " + columnComment);
                System.out.print("\ndataType: " + dataType);
                System.out.print("\nIsIdentity: " + IsIdentity);
                System.out.print("\nIsPK: " + IsPK);
                System.out.print("\n");

                String fieldName="";
                String cnames[]=columnName.split("_");
                for(String n:cnames){
                    if(!"t".equals(n)){
                        fieldName+= StringUtils.makeFirstCharUpcase(n);
                    }
                }
                fieldName=StringUtils.makeFirstCharLowercase(fieldName);
                System.out.printf("fieldName->"+fieldName);
                String fieldType="";
                dataType=dataType.toUpperCase();
                if(dataType.endsWith("INT")||dataType.startsWith("INT")){
                    fieldType="int";
                    if(dataType.equals("BIGINT")){
                        fieldType="long";
                    }
                }else if(dataType.equals("FLOAT")){
                    fieldType="float";
                }else if(dataType.equals("DOUBLE")){
                    fieldType="double";
                }else if(dataType.equals("DECIMAL")){
                    fieldType="double";
                }else if(dataType.equals("DATE")||dataType.equals("TIME")||dataType.equals("YEAR")||dataType.equals("DATETIME")||dataType.equals("TIMESTAMP")){
                    fieldType="Date";
                }else{
                    fieldType="String";
                }
                System.out.printf("fieldType->"+fieldType);
                boolean primary=false;
                if("1".equals(IsPK)){
                    primary=true;
                }
                boolean increment=false;
                if("1".equals(IsIdentity)){
                    increment=true;
                }
                WsdtField wsdtField=new WsdtField(fieldName,fieldType,columnName,columnComment,primary,increment);
                try {
                    JSONObject jsonObject = JSONObject.fromObject(columnComment);
                    Map<String,Class> classMap=new HashMap<>();
                    classMap.put("enumItems", WsdtFieldDesc.EnumItem.class);
                    classMap.put("relatedEntity", WsdtFieldDesc.RelatedEntity.class);
                    WsdtFieldDesc wsdtFieldDesc = (WsdtFieldDesc) JSONObject.toBean(jsonObject, WsdtFieldDesc.class,classMap);
                    if(wsdtFieldDesc.getRelatedEntity()!=null){
                        wsdtFieldDesc.getRelatedEntity().getTableName();
                        String en[]=wsdtFieldDesc.getRelatedEntity().getTableName().split("_");
                        String entity="";
                        for(String n:en){
                            if(!"t".equals(n)){
                                entity+= StringUtils.makeFirstCharUpcase(n);
                            }
                        }
                        wsdtFieldDesc.getRelatedEntity().setEntityName(entity);

                        String fn[]= wsdtFieldDesc.getRelatedEntity().getValueColumn().split("_");
                        String f="";
                        for(String n:fn){
                            if(!"t".equals(n)){
                                f+= StringUtils.makeFirstCharUpcase(n);
                            }
                        }
                        f=StringUtils.makeFirstCharLowercase(f);
                        wsdtFieldDesc.getRelatedEntity().setValueField(f);

                        fn= wsdtFieldDesc.getRelatedEntity().getTextColumn().split("_");
                        f="";
                        for(String n:fn){
                            if(!"t".equals(n)){
                                f+= StringUtils.makeFirstCharUpcase(n);
                            }
                        }
                        f=StringUtils.makeFirstCharLowercase(f);
                        wsdtFieldDesc.getRelatedEntity().setTextField(f);
                    }
                    wsdtField.setWsdtFieldDesc(wsdtFieldDesc);
                    wsdtField.setDescription(wsdtFieldDesc.getDesc());
                }catch (JSONException ex){
                    System.err.println("表字段comment不是json！");
                }
                wsdtFieldList.add(wsdtField);
            }
            if(wsdtFieldList.isEmpty()){
                System.err.println("表或表字段信息没有找到！");
                return null;
            }
            // 完成后关闭
            rs.close();
            stmt.close();

            //获取表信息
            stmt = conn.createStatement();
            sql = "SELECT\n" +
                    "    TABLE_NAME,\n" +
                    "    TABLE_COMMENT\n" +
                    "FROM\n" +
                    "    information_schema.`TABLES`\n" +
                    "WHERE\n" +
                    "    TABLE_SCHEMA = '"+dbConfig.getDbName()+"' -- dm 是数据库名称，需替换\n" +
                    "\t\tAND TABLE_NAME = '"+tableName+"' -- base_auth_resource 是表名，需替换\n" +
                    "ORDER BY\n" +
                    "    TABLE_NAME;";
            rs = stmt.executeQuery(sql);

            System.out.println("entityName->"+entityName);

            // 展开结果集数据库
            if(rs.next()){
                // 通过字段检索
                //String tableName  = rs.getString("TABLE_NAME");
                String tableComment = rs.getString("TABLE_COMMENT");
                wsdtEntity.setDescription(tableComment);
                try {
                    JSONObject jsonObject = JSONObject.fromObject(tableComment);
                    WsdtEntityDesc wsdtEntityDesc = (WsdtEntityDesc) JSONObject.toBean(jsonObject, WsdtEntityDesc.class);
                    wsdtEntity.setWsdtEntityDesc(wsdtEntityDesc);
                    wsdtEntity.setDescription(wsdtEntityDesc.getDesc());
                }catch (JSONException ex){
                    System.err.println("表字段comment不是json！");
                }
            }
            if(wsdtFieldList.isEmpty()){
                System.err.println("表或表字段信息没有找到！");
                return null;
            }
            // 完成后关闭
            rs.close();
            stmt.close();



            conn.close();
        }catch(SQLException se){
            // 处理 JDBC 错误
            se.printStackTrace();
        }catch(Exception e){
            // 处理 Class.forName 错误
            e.printStackTrace();
        }finally{
            // 关闭资源
            try{
                if(stmt!=null) stmt.close();
            }catch(SQLException se2){
            }// 什么都不做
            try{
                if(conn!=null) conn.close();
            }catch(SQLException se){
                se.printStackTrace();
            }
        }
        return wsdtEntity;
    }
}
